<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>Cookbook &raquo; Static Tasking | Taskflow QuickStart</title>
  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,400i,600,600i%7CSource+Code+Pro:400,400i,600" />
  <link rel="stylesheet" href="m-dark+documentation.compiled.css" />
  <link rel="icon" href="favicon.ico" type="image/x-icon" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <meta name="theme-color" content="#22272e" />
</head>
<body>
<header><nav id="navigation">
  <div class="m-container">
    <div class="m-row">
      <span id="m-navbar-brand" class="m-col-t-8 m-col-m-none m-left-m">
        <a href="https://taskflow.github.io"><img src="taskflow_logo.png" alt="" />Taskflow</a> <span class="m-breadcrumb">|</span> <a href="index.html" class="m-thin">QuickStart</a>
      </span>
      <div class="m-col-t-4 m-hide-m m-text-right m-nopadr">
        <a href="#search" class="m-doc-search-icon" title="Search" onclick="return showSearch()"><svg style="height: 0.9rem;" viewBox="0 0 16 16">
          <path id="m-doc-search-icon-path" d="m6 0c-3.31 0-6 2.69-6 6 0 3.31 2.69 6 6 6 1.49 0 2.85-0.541 3.89-1.44-0.0164 0.338 0.147 0.759 0.5 1.15l3.22 3.79c0.552 0.614 1.45 0.665 2 0.115 0.55-0.55 0.499-1.45-0.115-2l-3.79-3.22c-0.392-0.353-0.812-0.515-1.15-0.5 0.895-1.05 1.44-2.41 1.44-3.89 0-3.31-2.69-6-6-6zm0 1.56a4.44 4.44 0 0 1 4.44 4.44 4.44 4.44 0 0 1-4.44 4.44 4.44 4.44 0 0 1-4.44-4.44 4.44 4.44 0 0 1 4.44-4.44z"/>
        </svg></a>
        <a id="m-navbar-show" href="#navigation" title="Show navigation"></a>
        <a id="m-navbar-hide" href="#" title="Hide navigation"></a>
      </div>
      <div id="m-navbar-collapse" class="m-col-t-12 m-show-m m-col-m-none m-right-m">
        <div class="m-row">
          <ol class="m-col-t-6 m-col-m-none">
            <li><a href="pages.html">Handbook</a></li>
            <li><a href="namespaces.html">Namespaces</a></li>
          </ol>
          <ol class="m-col-t-6 m-col-m-none" start="3">
            <li><a href="annotated.html">Classes</a></li>
            <li><a href="files.html">Files</a></li>
            <li class="m-show-m"><a href="#search" class="m-doc-search-icon" title="Search" onclick="return showSearch()"><svg style="height: 0.9rem;" viewBox="0 0 16 16">
              <use href="#m-doc-search-icon-path" />
            </svg></a></li>
          </ol>
        </div>
      </div>
    </div>
  </div>
</nav></header>
<main><article>
  <div class="m-container m-container-inflatable">
    <div class="m-row">
      <div class="m-col-l-10 m-push-l-1">
        <h1>
          <span class="m-breadcrumb"><a href="Cookbook.html">Cookbook</a> &raquo;</span>
          Static Tasking
        </h1>
        <nav class="m-block m-default">
          <h3>Contents</h3>
          <ul>
            <li><a href="#CreateATaskDependencyGraph">Create a Task Dependency Graph</a></li>
            <li><a href="#VisualizeATaskDependencyGraph">Visualize a Task Dependency Graph</a></li>
            <li><a href="#ModifyTaskAttributes">Modify Task Attributes</a></li>
            <li><a href="#TraverseAdjacentTasks">Traverse Adjacent Tasks</a></li>
            <li><a href="#AttachUserDataToATask">Attach User Data to a Task</a></li>
            <li><a href="#UnderstandTheLifetimeOfATask">Understand the Lifetime of a Task</a></li>
            <li><a href="#MoveATaskflow">Move a Taskflow</a></li>
          </ul>
        </nav>
<p>This chapter demonstrates how to create a static task dependency graph. Static tasking captures the static parallel structure of a decomposition and is defined only by the program itself. It has a flat task hierarchy and cannot spawn new tasks from a running dependency graph.</p><section id="CreateATaskDependencyGraph"><h2><a href="#CreateATaskDependencyGraph">Create a Task Dependency Graph</a></h2><p>A task in Taskflow is a <em>callable</em> object for which the operation <a href="https://en.cppreference.com/w/cpp/utility/functional/invoke">std::<wbr />invoke</a> is applicable. It can be either a functor, a lambda expression, a bind expression, or a class objects with <code>operator()</code> overloaded. All tasks are created from <a href="classtf_1_1Taskflow.html" class="m-doc">tf::<wbr />Taskflow</a>, the class that manages a task dependency graph. Taskflow provides two methods, <a href="classtf_1_1FlowBuilder.html#acab0b4ac82260f47fdb36a3244ee3aaf" class="m-doc">tf::<wbr />Taskflow::<wbr />placeholder</a> and <a href="classtf_1_1FlowBuilder.html#a60d7a666cab71ecfa3010b2efb0d6b57" class="m-doc">tf::<wbr />Taskflow::<wbr />emplace</a> to create a task.</p><pre class="m-code"><span class="mi">1</span><span class="o">:</span><span class="w"> </span><span class="n">tf</span><span class="o">::</span><span class="n">Taskflow</span><span class="w"> </span><span class="n">taskflow</span><span class="p">;</span>
<span class="mi">2</span><span class="o">:</span><span class="w"> </span><span class="n">tf</span><span class="o">::</span><span class="n">Task</span><span class="w"> </span><span class="n">A</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">taskflow</span><span class="p">.</span><span class="n">placeholder</span><span class="p">();</span>
<span class="mi">3</span><span class="o">:</span><span class="w"> </span><span class="n">tf</span><span class="o">::</span><span class="n">Task</span><span class="w"> </span><span class="n">B</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">taskflow</span><span class="p">.</span><span class="n">emplace</span><span class="p">([]</span><span class="w"> </span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="s">&quot;task B</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">;</span><span class="w"> </span><span class="p">});</span>
<span class="mi">4</span><span class="o">:</span>
<span class="mi">5</span><span class="o">:</span><span class="w"> </span><span class="k">auto</span><span class="w"> </span><span class="p">[</span><span class="n">D</span><span class="p">,</span><span class="w"> </span><span class="n">E</span><span class="p">,</span><span class="w"> </span><span class="n">F</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">taskflow</span><span class="p">.</span><span class="n">emplace</span><span class="p">(</span>
<span class="mi">6</span><span class="o">:</span><span class="w">   </span><span class="p">[](){</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="s">&quot;Task A</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">;</span><span class="w"> </span><span class="p">},</span>
<span class="mi">7</span><span class="o">:</span><span class="w">   </span><span class="p">[](){</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="s">&quot;Task B</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">;</span><span class="w"> </span><span class="p">},</span>
<span class="mi">8</span><span class="o">:</span><span class="w">   </span><span class="p">[](){</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="s">&quot;Task C</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">;</span><span class="w"> </span><span class="p">}</span>
<span class="mi">9</span><span class="o">:</span><span class="w"> </span><span class="p">);</span></pre><p>Debrief:</p><ul><li>Line 1 creates a taskflow object, or a <em>graph</em></li><li>Line 2 creates a placeholder task without work (i.e., callable)</li><li>Line 3 creates a task from a given callable object and returns a task handle</li><li>Lines 5-9 create three tasks in one call using C++ structured binding coupled with <a href="http://en.cppreference.com/w/cpp/utility/tuple.html" class="m-doc-external">std::<wbr />tuple</a></li></ul><p>Each time you create a task, the taskflow object creates a node in the task graph and returns a task handle of type <a href="classtf_1_1Task.html" class="m-doc">tf::<wbr />Task</a>. A task handle is a lightweight object that wraps up a particular node in a graph and provides a set of methods for you to assign different attributes to the task such as adding dependencies, naming, and assigning a new work.</p><pre class="m-code"><span class="w"> </span><span class="mi">1</span><span class="o">:</span><span class="w"> </span><span class="n">tf</span><span class="o">::</span><span class="n">Taskflow</span><span class="w"> </span><span class="n">taskflow</span><span class="p">;</span>
<span class="w"> </span><span class="mi">2</span><span class="o">:</span><span class="w"> </span><span class="n">tf</span><span class="o">::</span><span class="n">Task</span><span class="w"> </span><span class="n">A</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">taskflow</span><span class="p">.</span><span class="n">emplace</span><span class="p">([]</span><span class="w"> </span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="s">&quot;create a task A</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">;</span><span class="w"> </span><span class="p">});</span>
<span class="w"> </span><span class="mi">3</span><span class="o">:</span><span class="w"> </span><span class="n">tf</span><span class="o">::</span><span class="n">Task</span><span class="w"> </span><span class="n">B</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">taskflow</span><span class="p">.</span><span class="n">emplace</span><span class="p">([]</span><span class="w"> </span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="s">&quot;create a task B</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">;</span><span class="w"> </span><span class="p">});</span>
<span class="w"> </span><span class="mi">4</span><span class="o">:</span>
<span class="w"> </span><span class="mi">5</span><span class="o">:</span><span class="w"> </span><span class="n">A</span><span class="p">.</span><span class="n">name</span><span class="p">(</span><span class="s">&quot;TaskA&quot;</span><span class="p">);</span>
<span class="w"> </span><span class="mi">6</span><span class="o">:</span><span class="w"> </span><span class="n">A</span><span class="p">.</span><span class="n">work</span><span class="p">([]</span><span class="w"> </span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="s">&quot;reassign A to a new callable</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">;</span><span class="w"> </span><span class="p">});</span>
<span class="w"> </span><span class="mi">7</span><span class="o">:</span><span class="w"> </span><span class="n">A</span><span class="p">.</span><span class="n">precede</span><span class="p">(</span><span class="n">B</span><span class="p">);</span>
<span class="w"> </span><span class="mi">8</span><span class="o">:</span>
<span class="w"> </span><span class="mi">9</span><span class="o">:</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="n">A</span><span class="p">.</span><span class="n">name</span><span class="p">()</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span><span class="w">            </span><span class="c1">// TaskA</span>
<span class="mi">10</span><span class="o">:</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="n">A</span><span class="p">.</span><span class="n">num_successors</span><span class="p">()</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span><span class="w">  </span><span class="c1">// 1</span>
<span class="mi">11</span><span class="o">:</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="n">A</span><span class="p">.</span><span class="n">num_dependents</span><span class="p">()</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span><span class="w">  </span><span class="c1">// 0</span>
<span class="mi">12</span><span class="o">:</span><span class="w"> </span>
<span class="mi">13</span><span class="o">:</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="n">B</span><span class="p">.</span><span class="n">num_successors</span><span class="p">()</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span><span class="w">  </span><span class="c1">// 0</span>
<span class="mi">14</span><span class="o">:</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="n">B</span><span class="p">.</span><span class="n">num_dependents</span><span class="p">()</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span><span class="w">  </span><span class="c1">// 1</span></pre><p>Debrief:</p><ul><li>Line 1 creates a taskflow object</li><li>Lines 2-3 create two tasks A and B</li><li>Lines 5-6 assign a name and a work to task A, and add a precedence link to task B</li><li>Line 7 adds a dependency link from A to B</li><li>Lines 9-14 dump the task attributes</li></ul><p>Taskflow uses general-purpose polymorphic function wrapper, <a href="http://en.cppreference.com/w/cpp/utility/functional/function.html" class="m-doc-external">std::<wbr />function</a>, to store and invoke a callable in a task. You need to follow its contract to create a task. For example, the callable to construct a task must be copyable, and thus the code below won&#x27;t compile:</p><pre class="m-code"><span class="n">taskflow</span><span class="p">.</span><span class="n">emplace</span><span class="p">([</span><span class="n">ptr</span><span class="o">=</span><span class="n">std</span><span class="o">::</span><span class="n">make_unique</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="p">(</span><span class="mi">1</span><span class="p">)](){</span>
<span class="w">  </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="s">&quot;captured unique pointer is not copyable&quot;</span><span class="p">;</span>
<span class="p">});</span></pre></section><section id="VisualizeATaskDependencyGraph"><h2><a href="#VisualizeATaskDependencyGraph">Visualize a Task Dependency Graph</a></h2><p>You can dump a taskflow to a DOT format and visualize the graph using free online tools such as <a href="https://dreampuf.github.io/GraphvizOnline/">GraphvizOnline</a> and <a href="http://www.webgraphviz.com/">WebGraphviz</a>.</p><pre class="m-code"><span class="w"> </span><span class="mi">1</span><span class="o">:</span><span class="w"> </span><span class="err">#</span><span class="n">include</span><span class="w"> </span><span class="o">&lt;</span><span class="n">taskflow</span><span class="o">/</span><span class="n">taskflow</span><span class="p">.</span><span class="n">hpp</span><span class="o">&gt;</span>
<span class="w"> </span><span class="mi">2</span><span class="o">:</span>
<span class="w"> </span><span class="mi">3</span><span class="o">:</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="mi">4</span><span class="o">:</span><span class="w"> </span>
<span class="w"> </span><span class="mi">5</span><span class="o">:</span><span class="w">   </span><span class="n">tf</span><span class="o">::</span><span class="n">Taskflow</span><span class="w"> </span><span class="n">taskflow</span><span class="p">;</span>
<span class="w"> </span><span class="mi">6</span><span class="o">:</span>
<span class="w"> </span><span class="mi">7</span><span class="o">:</span><span class="w">   </span><span class="c1">// create a task dependency graph</span>
<span class="w"> </span><span class="mi">8</span><span class="o">:</span><span class="w">   </span><span class="n">tf</span><span class="o">::</span><span class="n">Task</span><span class="w"> </span><span class="n">A</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">taskflow</span><span class="p">.</span><span class="n">emplace</span><span class="p">([]</span><span class="w"> </span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="s">&quot;Task A</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">;</span><span class="w"> </span><span class="p">});</span>
<span class="w"> </span><span class="mi">9</span><span class="o">:</span><span class="w">   </span><span class="n">tf</span><span class="o">::</span><span class="n">Task</span><span class="w"> </span><span class="n">B</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">taskflow</span><span class="p">.</span><span class="n">emplace</span><span class="p">([]</span><span class="w"> </span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="s">&quot;Task B</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">;</span><span class="w"> </span><span class="p">});</span>
<span class="mi">10</span><span class="o">:</span><span class="w">   </span><span class="n">tf</span><span class="o">::</span><span class="n">Task</span><span class="w"> </span><span class="n">C</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">taskflow</span><span class="p">.</span><span class="n">emplace</span><span class="p">([]</span><span class="w"> </span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="s">&quot;Task C</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">;</span><span class="w"> </span><span class="p">});</span>
<span class="mi">11</span><span class="o">:</span><span class="w">   </span><span class="n">tf</span><span class="o">::</span><span class="n">Task</span><span class="w"> </span><span class="n">D</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">taskflow</span><span class="p">.</span><span class="n">emplace</span><span class="p">([]</span><span class="w"> </span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="s">&quot;Task D</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">;</span><span class="w"> </span><span class="p">});</span>
<span class="mi">12</span><span class="o">:</span>
<span class="mi">13</span><span class="o">:</span><span class="w">   </span><span class="c1">// add dependency links</span>
<span class="mi">14</span><span class="o">:</span><span class="w">   </span><span class="n">A</span><span class="p">.</span><span class="n">precede</span><span class="p">(</span><span class="n">B</span><span class="p">);</span><span class="w"> </span>
<span class="mi">15</span><span class="o">:</span><span class="w">   </span><span class="n">A</span><span class="p">.</span><span class="n">precede</span><span class="p">(</span><span class="n">C</span><span class="p">);</span>
<span class="mi">16</span><span class="o">:</span><span class="w">   </span><span class="n">B</span><span class="p">.</span><span class="n">precede</span><span class="p">(</span><span class="n">D</span><span class="p">);</span>
<span class="mi">17</span><span class="o">:</span><span class="w">   </span><span class="n">C</span><span class="p">.</span><span class="n">precede</span><span class="p">(</span><span class="n">D</span><span class="p">);</span>
<span class="mi">18</span><span class="o">:</span>
<span class="mi">19</span><span class="o">:</span><span class="w">   </span><span class="n">taskflow</span><span class="p">.</span><span class="n">dump</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="p">);</span>
<span class="mi">20</span><span class="o">:</span><span class="w"> </span><span class="p">}</span></pre><p>Debrief:</p><ul><li>Line 5 creates a taskflow object</li><li>Lines 8-11 create four tasks</li><li>Lines 14-17 add four task dependencies</li><li>Line 19 dumps the taskflow in the DOT format through standard output</li></ul><div class="m-graph"><svg style="width: 24.200rem; height: 9.800rem;" viewBox="0.00 0.00 242.00 98.00">
<g transform="scale(1 1) rotate(0) translate(4 94)">
<title>G</title>
<g class="m-node m-flat">
<title>A</title>
<ellipse cx="27" cy="-45" rx="27" ry="18"/>
<text text-anchor="middle" x="27" y="-41.12" font-family="Helvetica,sans-Serif" font-size="10.00">A</text>
</g>
<g class="m-node m-flat">
<title>B</title>
<ellipse cx="117" cy="-72" rx="27" ry="18"/>
<text text-anchor="middle" x="117" y="-68.12" font-family="Helvetica,sans-Serif" font-size="10.00">B</text>
</g>
<g class="m-edge">
<title>A&#45;&gt;B</title>
<path d="M52.05,-52.38C60.97,-55.12 71.29,-58.28 80.99,-61.26"/>
<polygon points="79.95,-64.6 90.54,-64.19 82,-57.91 79.95,-64.6"/>
</g>
<g class="m-node m-flat">
<title>C</title>
<ellipse cx="117" cy="-18" rx="27" ry="18"/>
<text text-anchor="middle" x="117" y="-14.12" font-family="Helvetica,sans-Serif" font-size="10.00">C</text>
</g>
<g class="m-edge">
<title>A&#45;&gt;C</title>
<path d="M52.05,-37.62C60.97,-34.88 71.29,-31.72 80.99,-28.74"/>
<polygon points="82,-32.09 90.54,-25.81 79.95,-25.4 82,-32.09"/>
</g>
<g class="m-node m-flat">
<title>D</title>
<ellipse cx="207" cy="-45" rx="27" ry="18"/>
<text text-anchor="middle" x="207" y="-41.12" font-family="Helvetica,sans-Serif" font-size="10.00">D</text>
</g>
<g class="m-edge">
<title>B&#45;&gt;D</title>
<path d="M142.05,-64.62C150.97,-61.88 161.29,-58.72 170.99,-55.74"/>
<polygon points="172,-59.09 180.54,-52.81 169.95,-52.4 172,-59.09"/>
</g>
<g class="m-edge">
<title>C&#45;&gt;D</title>
<path d="M142.05,-25.38C150.97,-28.12 161.29,-31.28 170.99,-34.26"/>
<polygon points="169.95,-37.6 180.54,-37.19 172,-30.91 169.95,-37.6"/>
</g>
</g>
</svg>
</div></section><section id="ModifyTaskAttributes"><h2><a href="#ModifyTaskAttributes">Modify Task Attributes</a></h2><p>This example demonstrates how to modify a task&#x27;s attributes using methods defined in the task handler.</p><pre class="m-code"><span class="w"> </span><span class="mi">1</span><span class="o">:</span><span class="w"> </span><span class="err">#</span><span class="n">include</span><span class="w"> </span><span class="o">&lt;</span><span class="n">taskflow</span><span class="o">/</span><span class="n">taskflow</span><span class="p">.</span><span class="n">hpp</span><span class="o">&gt;</span>
<span class="w"> </span><span class="mi">2</span><span class="o">:</span>
<span class="w"> </span><span class="mi">3</span><span class="o">:</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="mi">4</span><span class="o">:</span>
<span class="w"> </span><span class="mi">5</span><span class="o">:</span><span class="w">   </span><span class="n">tf</span><span class="o">::</span><span class="n">Taskflow</span><span class="w"> </span><span class="n">taskflow</span><span class="p">;</span>
<span class="w"> </span><span class="mi">6</span><span class="o">:</span>
<span class="w"> </span><span class="mi">7</span><span class="o">:</span><span class="w">   </span><span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">tf</span><span class="o">::</span><span class="n">Task</span><span class="o">&gt;</span><span class="w"> </span><span class="n">tasks</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span><span class="w"> </span>
<span class="w"> </span><span class="mi">8</span><span class="o">:</span><span class="w">     </span><span class="n">taskflow</span><span class="p">.</span><span class="n">placeholder</span><span class="p">(),</span><span class="w">         </span><span class="c1">// create a task with no work</span>
<span class="w"> </span><span class="mi">9</span><span class="o">:</span><span class="w">     </span><span class="n">taskflow</span><span class="p">.</span><span class="n">placeholder</span><span class="p">()</span><span class="w">          </span><span class="c1">// create a task with no work</span>
<span class="mi">10</span><span class="o">:</span><span class="w">   </span><span class="p">};</span>
<span class="mi">11</span><span class="o">:</span>
<span class="mi">12</span><span class="o">:</span><span class="w">   </span><span class="n">tasks</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">name</span><span class="p">(</span><span class="s">&quot;This is Task 0&quot;</span><span class="p">);</span>
<span class="mi">13</span><span class="o">:</span><span class="w">   </span><span class="n">tasks</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">name</span><span class="p">(</span><span class="s">&quot;This is Task 1&quot;</span><span class="p">);</span>
<span class="mi">14</span><span class="o">:</span><span class="w">   </span><span class="n">tasks</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">precede</span><span class="p">(</span><span class="n">tasks</span><span class="p">[</span><span class="mi">1</span><span class="p">]);</span>
<span class="mi">15</span><span class="o">:</span>
<span class="mi">16</span><span class="o">:</span><span class="w">   </span><span class="k">for</span><span class="p">(</span><span class="k">auto</span><span class="w"> </span><span class="n">task</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">tasks</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">          </span><span class="c1">// print out each task&#39;s attributes</span>
<span class="mi">17</span><span class="o">:</span><span class="w">     </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="n">task</span><span class="p">.</span><span class="n">name</span><span class="p">()</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="s">&quot;: &quot;</span>
<span class="mi">18</span><span class="o">:</span><span class="w">               </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="s">&quot;num_dependents=&quot;</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="n">task</span><span class="p">.</span><span class="n">num_dependents</span><span class="p">()</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="s">&quot;, &quot;</span>
<span class="mi">19</span><span class="o">:</span><span class="w">               </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="s">&quot;num_successors=&quot;</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="n">task</span><span class="p">.</span><span class="n">num_successors</span><span class="p">()</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="sc">&#39;\n&#39;</span><span class="p">;</span>
<span class="mi">20</span><span class="o">:</span><span class="w">   </span><span class="p">}</span>
<span class="mi">21</span><span class="o">:</span>
<span class="mi">22</span><span class="o">:</span><span class="w">   </span><span class="n">taskflow</span><span class="p">.</span><span class="n">dump</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="p">);</span><span class="w">         </span><span class="c1">// dump the taskflow graph</span>
<span class="mi">23</span><span class="o">:</span>
<span class="mi">24</span><span class="o">:</span><span class="w">   </span><span class="n">tasks</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">work</span><span class="p">([](){</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="s">&quot;got a new work!</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">;</span><span class="w"> </span><span class="p">});</span>
<span class="mi">25</span><span class="o">:</span><span class="w">   </span><span class="n">tasks</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">work</span><span class="p">([](){</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="s">&quot;got a new work!</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">;</span><span class="w"> </span><span class="p">});</span>
<span class="mi">26</span><span class="o">:</span>
<span class="mi">27</span><span class="o">:</span><span class="w">   </span><span class="k">return</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
<span class="mi">28</span><span class="o">:</span><span class="w"> </span><span class="p">}</span></pre><p>The output of this program looks like the following:</p><pre class="m-code">This<span class="w"> </span>is<span class="w"> </span>Task<span class="w"> </span><span class="m">0</span>:<span class="w"> </span><span class="nv">num_dependents</span><span class="o">=</span><span class="m">0</span>,<span class="w"> </span><span class="nv">num_successors</span><span class="o">=</span><span class="m">1</span>
This<span class="w"> </span>is<span class="w"> </span>Task<span class="w"> </span><span class="m">1</span>:<span class="w"> </span><span class="nv">num_dependents</span><span class="o">=</span><span class="m">1</span>,<span class="w"> </span><span class="nv">num_successors</span><span class="o">=</span><span class="m">0</span>
digraph<span class="w"> </span>Taskflow<span class="w"> </span><span class="o">{</span>
<span class="s2">&quot;This is Task 1&quot;</span><span class="p">;</span>
<span class="s2">&quot;This is Task 0&quot;</span><span class="p">;</span>
<span class="s2">&quot;This is Task 0&quot;</span><span class="w"> </span>-&gt;<span class="w"> </span><span class="s2">&quot;This is Task 1&quot;</span><span class="p">;</span>
<span class="o">}</span></pre><p>Debrief:</p><ul><li>Line 5 creates a taskflow object</li><li>Lines 7-10 create two placeholder tasks with no works and stores the corresponding task handles in a vector</li><li>Lines 12-13 name the two tasks with human-readable strings</li><li>Line 14 adds a dependency link from the first task to the second task</li><li>Lines 16-20 print out the name of each task, the number of dependents, and the number of successors</li><li>Line 22 dumps the task dependency graph to a <a href="https://dreampuf.github.io/GraphvizOnline/">GraphViz Online</a> format (dot)</li><li>Lines 24-25 assign a new target to each task</li></ul><p>You can change the name and work of a task at anytime before running the graph. The later assignment overwrites the previous values.</p></section><section id="TraverseAdjacentTasks"><h2><a href="#TraverseAdjacentTasks">Traverse Adjacent Tasks</a></h2><p>You can iterate the successor list and the dependent list of a task by using <a href="classtf_1_1Task.html#aff13a503d4a3c994eb08cb6f22e1b427" class="m-doc">tf::<wbr />Task::<wbr />for_each_successor</a> and <a href="classtf_1_1Task.html#a3bf68937662bf291637e4a763476b2e4" class="m-doc">tf::<wbr />Task::<wbr />for_each_dependent</a>, respectively. Each method takes a lambda and applies it to a successor or a dependent being traversed.</p><pre class="m-code"><span class="c1">// traverse all successors of my_task</span>
<span class="n">my_task</span><span class="p">.</span><span class="n">for_each_successor</span><span class="p">([</span><span class="n">s</span><span class="o">=</span><span class="mi">0</span><span class="p">]</span><span class="w"> </span><span class="p">(</span><span class="n">tf</span><span class="o">::</span><span class="n">Task</span><span class="w"> </span><span class="n">successor</span><span class="p">)</span><span class="w"> </span><span class="k">mutable</span><span class="w"> </span><span class="p">{</span>
<span class="w">  </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="s">&quot;successor &quot;</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="n">s</span><span class="o">++</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="sc">&#39;\n&#39;</span><span class="p">;</span>
<span class="p">});</span>

<span class="c1">// traverse all dependents of my_task</span>
<span class="n">my_task</span><span class="p">.</span><span class="n">for_each_dependent</span><span class="p">([</span><span class="n">d</span><span class="o">=</span><span class="mi">0</span><span class="p">]</span><span class="w"> </span><span class="p">(</span><span class="n">tf</span><span class="o">::</span><span class="n">Task</span><span class="w"> </span><span class="n">dependent</span><span class="p">)</span><span class="w"> </span><span class="k">mutable</span><span class="w"> </span><span class="p">{</span>
<span class="w">  </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="s">&quot;dependent &quot;</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="n">d</span><span class="o">++</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="sc">&#39;\n&#39;</span><span class="p">;</span>
<span class="p">});</span></pre></section><section id="AttachUserDataToATask"><h2><a href="#AttachUserDataToATask">Attach User Data to a Task</a></h2><p>You can attach custom data to a task using <a href="classtf_1_1Task.html#afd82ab6d6518d1142a72c4d2c97ff114" class="m-doc">tf::<wbr />Task::<wbr />data(void*)</a> and access it using <a href="classtf_1_1Task.html#afd82ab6d6518d1142a72c4d2c97ff114" class="m-doc">tf::<wbr />Task::<wbr />data()</a>. Each node in a taskflow is associated with a C-styled data pointer (i.e., <code>void*</code>) you can use to point to user data and access it in the body of a task callable. The following example attaches an integer to a task and accesses that integer through capturing the data in the callable.</p><pre class="m-code"><span class="kt">int</span><span class="w"> </span><span class="n">my_data</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">5</span><span class="p">;</span>
<span class="n">tf</span><span class="o">::</span><span class="n">Task</span><span class="w"> </span><span class="n">task</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">taskflow</span><span class="p">.</span><span class="n">placeholder</span><span class="p">();</span>
<span class="n">task</span><span class="p">.</span><span class="n">data</span><span class="p">(</span><span class="o">&amp;</span><span class="n">my_data</span><span class="p">)</span>
<span class="w">    </span><span class="p">.</span><span class="n">work</span><span class="p">([</span><span class="n">task</span><span class="p">](){</span>
<span class="w">      </span><span class="kt">int</span><span class="w"> </span><span class="n">my_date</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">*</span><span class="k">static_cast</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">*&gt;</span><span class="p">(</span><span class="n">task</span><span class="p">.</span><span class="n">data</span><span class="p">());</span>
<span class="w">      </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="s">&quot;my_data: &quot;</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="n">my_data</span><span class="p">;</span><span class="w"> </span>
<span class="w">    </span><span class="p">});</span></pre><p>Notice that you need to create a placeholder task first before assigning it a work callable. Only this way can you capture that task in the lambda and access its attached data in the lambda body.</p><aside class="m-note m-warning"><h4>Attention</h4><p>It is your responsibility to ensure that the attached data stay alive during the execution of its task.</p></aside></section><section id="UnderstandTheLifetimeOfATask"><h2><a href="#UnderstandTheLifetimeOfATask">Understand the Lifetime of a Task</a></h2><p>A task lives with its graph and belongs to only a graph at a time, and is not destroyed until the graph gets cleaned up. The lifetime of a task refers to the user-given callable object, including captured values. As long as the graph is alive, all the associated tasks exist.</p><aside class="m-note m-warning"><h4>Attention</h4><p>It is your responsibility to keep tasks and graph alive during their execution.</p></aside></section><section id="MoveATaskflow"><h2><a href="#MoveATaskflow">Move a Taskflow</a></h2><p>You can construct or assign a taskflow from a <em>moved</em> taskflow. Moving a taskflow to another will result in transferring the underlying graph data structures from one to the other.</p><pre class="m-code"><span class="n">tf</span><span class="o">::</span><span class="n">Taskflow</span><span class="w"> </span><span class="n">taskflow1</span><span class="p">,</span><span class="w"> </span><span class="n">taskflow3</span><span class="p">;</span>

<span class="n">taskflow1</span><span class="p">.</span><span class="n">emplace</span><span class="p">([](){});</span>

<span class="c1">// move-construct taskflow2 from taskflow1</span>
<span class="n">tf</span><span class="o">::</span><span class="n">Taskflow</span><span class="w"> </span><span class="nf">taskflow2</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">taskflow1</span><span class="p">));</span>
<span class="n">assert</span><span class="p">(</span><span class="n">taskflow2</span><span class="p">.</span><span class="n">num_tasks</span><span class="p">()</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="n">taskflow1</span><span class="p">.</span><span class="n">num_tasks</span><span class="p">()</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">0</span><span class="p">);</span>

<span class="c1">// move-assign taskflow3 to taskflow2</span>
<span class="n">taskflow3</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">taskflow2</span><span class="p">);</span>
<span class="n">assert</span><span class="p">(</span><span class="n">taskflow3</span><span class="p">.</span><span class="n">num_tasks</span><span class="p">()</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="n">taskflow2</span><span class="p">.</span><span class="n">num_tasks</span><span class="p">()</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">0</span><span class="p">);</span></pre><p>You can only move a taskflow to another while that taskflow is not being run by an executor. Moving a running taskflow can result in undefined behavior. Please see <a href="ExecuteTaskflow.html#ExecuteATaskflowWithTransferredOwnership" class="m-doc">Execute a Taskflow with Transferred Ownership</a> for more details.</p></section>
      </div>
    </div>
  </div>
</article></main>
<div class="m-doc-search" id="search">
  <a href="#!" onclick="return hideSearch()"></a>
  <div class="m-container">
    <div class="m-row">
      <div class="m-col-m-8 m-push-m-2">
        <div class="m-doc-search-header m-text m-small">
          <div><span class="m-label m-default">Tab</span> / <span class="m-label m-default">T</span> to search, <span class="m-label m-default">Esc</span> to close</div>
          <div id="search-symbolcount">&hellip;</div>
        </div>
        <div class="m-doc-search-content">
          <form>
            <input type="search" name="q" id="search-input" placeholder="Loading &hellip;" disabled="disabled" autofocus="autofocus" autocomplete="off" spellcheck="false" />
          </form>
          <noscript class="m-text m-danger m-text-center">Unlike everything else in the docs, the search functionality <em>requires</em> JavaScript.</noscript>
          <div id="search-help" class="m-text m-dim m-text-center">
            <p class="m-noindent">Search for symbols, directories, files, pages or
            modules. You can omit any prefix from the symbol or file path; adding a
            <code>:</code> or <code>/</code> suffix lists all members of given symbol or
            directory.</p>
            <p class="m-noindent">Use <span class="m-label m-dim">&darr;</span>
            / <span class="m-label m-dim">&uarr;</span> to navigate through the list,
            <span class="m-label m-dim">Enter</span> to go.
            <span class="m-label m-dim">Tab</span> autocompletes common prefix, you can
            copy a link to the result using <span class="m-label m-dim">⌘</span>
            <span class="m-label m-dim">L</span> while <span class="m-label m-dim">⌘</span>
            <span class="m-label m-dim">M</span> produces a Markdown link.</p>
          </div>
          <div id="search-notfound" class="m-text m-warning m-text-center">Sorry, nothing was found.</div>
          <ul id="search-results"></ul>
        </div>
      </div>
    </div>
  </div>
</div>
<script src="search-v2.js"></script>
<script src="searchdata-v2.js" async="async"></script>
<footer><nav>
  <div class="m-container">
    <div class="m-row">
      <div class="m-col-l-10 m-push-l-1">
        <p>Taskflow handbook is part of the <a href="https://taskflow.github.io">Taskflow project</a>, copyright © <a href="https://tsung-wei-huang.github.io/">Dr. Tsung-Wei Huang</a>, 2018&ndash;2024.<br />Generated by <a href="https://doxygen.org/">Doxygen</a> 1.9.6 and <a href="https://mcss.mosra.cz/">m.css</a>.</p>
      </div>
    </div>
  </div>
</nav></footer>
</body>
</html>
